#!/bin/sh
#
# Perform necessary datadog-agent setup steps before package is installed.
#
# .deb: STEP 2 of 5
# .rpm: STEP 2 of 6

INSTALL_DIR=/opt/datadog-agent
LOG_DIR=/var/log/datadog
SERVICE_NAME=datadog-agent

KNOWN_DISTRIBUTION="(Debian|Ubuntu|RedHat|CentOS|openSUSE|Amazon|Arista|SUSE)"
DISTRIBUTION=$(lsb_release -d 2>/dev/null | grep -Eo $KNOWN_DISTRIBUTION  || grep -Eo $KNOWN_DISTRIBUTION /etc/issue 2>/dev/null || grep -Eo $KNOWN_DISTRIBUTION /etc/Eos-release 2>/dev/null || grep -m1 -Eo $KNOWN_DISTRIBUTION /etc/os-release 2>/dev/null || uname -s)
if [ -f "/etc/debian_version" ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
    DISTRIBUTION_FAMILY="Debian"
fi
# Linux installation
if [ "$DISTRIBUTION" != "Darwin" ]; then
    set -e

    if [ -f "/lib/systemd/system/$SERVICE_NAME.service" ] || [ -f "/usr/lib/systemd/system/$SERVICE_NAME.service" ]; then
        # Stop an already running agent
        # Only supports systemd and upstart
        if command -v systemctl >/dev/null 2>&1; then
            systemctl stop $SERVICE_NAME-process || true
            systemctl stop $SERVICE_NAME-sysprobe || true
            systemctl stop $SERVICE_NAME-trace || true
            systemctl stop $SERVICE_NAME-security || true
            systemctl stop $SERVICE_NAME || true
        elif command -v initctl >/dev/null 2>&1; then
            initctl stop $SERVICE_NAME-process || true
            initctl stop $SERVICE_NAME-sysprobe || true
            initctl stop $SERVICE_NAME-trace || true
            initctl stop $SERVICE_NAME-security || true
            initctl stop $SERVICE_NAME || true
        elif [ "$DISTRIBUTION_FAMILY" = "Debian" ]; then
            if command -v service >/dev/null 2>&1; then
                service $SERVICE_NAME-process stop || true
                service $SERVICE_NAME-sysprobe stop || true
                service $SERVICE_NAME-trace stop || true
                service $SERVICE_NAME-security stop || true
                service $SERVICE_NAME stop || true
            else
                echo "[ WARNING ]\tCannot detect a supported init system. The datadog-agent package only provides service files for systemd, upstart and sysvinit."
            fi
        else
            echo "[ WARNING ]\tCannot detect a supported init system. The datadog-agent package only provides service files for systemd and upstart."
        fi
    fi

    # For versions < 6.10 using the custom datadog-pip, TUF and in-toto files were kept in TUF_REPO_DIR.
    # They were not being cleaned by these versions, so let's do that now on install/upgrade
    TUF_REPO_DIR=$INSTALL_DIR/repositories
    if [ -d $TUF_REPO_DIR ]; then
        rm -rf $TUF_REPO_DIR
    fi

    if [ -f "/etc/debian_version" ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
        # Nothing specific on Debian
        :
        #DEBHELPER#
    elif [ -f "/etc/redhat-release" ] || [ -f "/etc/system-release" ] || [ -f "/etc/SuSE-release" ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "openSUSE" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "Arista" ]; then
        # RPM Agents < 5.18.0 expect the preinst script of the _new_ package to stop the agent service on upgrade (which is defined with an init.d script on Agent 5)
        # So let's stop the Agent 5 service here until we don't want to support upgrades from Agents < 5.18.0 anymore
        if [ -f "/etc/init.d/datadog-agent" ]; then
            /etc/init.d/datadog-agent stop || true
        fi

        # Set up `dd-agent` user and group
        getent group dd-agent >/dev/null || groupadd -r dd-agent
        getent passwd dd-agent >/dev/null || \
            useradd -r -M -g dd-agent -d $INSTALL_DIR -s /sbin/nologin \
                -c "Datadog Agent" dd-agent && \
                { usermod -L dd-agent || echo "[ WARNING ]\tCannot lock the 'dd-agent' user account"; }


        # Starting with 6.10, integrations are also uninstalled on package removal

        # Since 6.18.0, a file containing all integrations files which have been installed by
        # the package is available. We use it to remove only the datadog-related check files which
        # have *NOT* been installed by the package (eg: installed using the `integration` command).

        if [ -f "$INSTALL_DIR/embedded/.installed_by_pkg.txt" ]; then
            echo "Removing integrations installed with the 'agent integration' command"

            # List all files in the embedded dir of the datadog-agent install dir
            PREV_DIR=$(pwd)
            cd $INSTALL_DIR
            find . -depth -path './embedded/lib/python*/site-packages/datadog_*' > $INSTALL_DIR/embedded/.all-integrations.txt

            # List all files in the embedded dir of the datadog-agent install dir
            # which were not installed by the package and rm them.
            grep -Fxv -f $INSTALL_DIR/embedded/.installed_by_pkg.txt $INSTALL_DIR/embedded/.all-integrations.txt | grep -v '^#' | xargs --no-run-if-empty -I '{}' rm -r $INSTALL_DIR/{}

            rm $INSTALL_DIR/embedded/.all-integrations.txt
            cd "$PREV_DIR"
        else
            PIP2_PATH=$INSTALL_DIR/embedded/bin/pip2
            PIP3_PATH=$INSTALL_DIR/embedded/bin/pip3
            if [ -x $PIP2_PATH ]; then
                echo "Uninstalling Python 2 integrations..."
                $PIP2_PATH freeze | grep ^datadog- | grep -v datadog-checks-base | xargs $PIP2_PATH uninstall -y -q --no-cache-dir || true
            fi
            if [ -x $PIP3_PATH ]; then
                echo "Uninstalling Python 3 integrations..."
                $PIP3_PATH freeze | grep ^datadog- | grep -v datadog-checks-base | xargs $PIP3_PATH uninstall -y -q --no-cache-dir || true
            fi
        fi

        # Delete all the .pyc/.pyo files in the embedded dir that are part of the old agent's package
        # This MUST be done after using pip or any python, because executing python might generate .pyc files
        if [ -f "$INSTALL_DIR/embedded/.py_compiled_files.txt" ]; then
            # (commented lines are filtered out)
            cat $INSTALL_DIR/embedded/.py_compiled_files.txt | grep -v '^#' | xargs rm -f
        fi

    else
        echo "[ FAILED ]\tYour system is currently not supported by this script.";
        exit 1;
    fi
else
    # macOS

    # On Mac, the real log folder is located under /opt/datadog-agent/logs, because some MacOS versions deletes
    # /var/log on upgrade. The old log folder now becomes a symbolic link to the new folder.
    REAL_LOG_DIR=/opt/datadog-agent/logs
    LOG_BASE_DIR=/var/log

    mkdir -p $REAL_LOG_DIR

    CONF_DIR="$INSTALL_DIR/etc"
    APP_DIR="/Applications/Datadog Agent.app"

    LOG_FILE="$REAL_LOG_DIR/preinstall.log"
    exec > $LOG_FILE 2>&1

    if [ -d $LOG_DIR ]; then
        # Old log folder exists
        echo "Old log folder exists."

        if [ -L $LOG_DIR ]; then
            # Old log folder is a symblic link already. Nothing to do here.
            echo "Old log folder is a link, nothing to do here."
            true
        else
            # Old log folder is not a link, copy the files to the new folder.
            echo "Old log folder is not a link, copying everything to the new location."
            cp -Rf $LOG_DIR/* $REAL_LOG_DIR

            # Remove the old one
            echo "Removing the old log folder."
            rm -rf $LOG_DIR

            # Create a link
            echo "Creating a link from old log folder to the new location."
            ln -s $REAL_LOG_DIR $LOG_DIR
        fi
    else
        # Old log folder does not exist. Try to create its base folder in case it does not exist either.
        echo "Old log folder does not exist. Creating its base folder."
        mkdir -p $LOG_BASE_DIR

        # Create a link
        echo "Creating a link from old log folder to the new location."
        ln -s $REAL_LOG_DIR $LOG_DIR
    fi
    echo "Log folder migration has completed."

    # Determine current user if he is using the Graphical installer
    # shellcheck disable=SC2009
    INSTALL_USER=$(ps aux | grep "CoreServices/Installer" | grep -v grep | awk '{print $1;}')

    # Otherwise, we hope he is using the install script and try to use this user
    # If it fails, no choice but to use root :'(
    if [ -z "$INSTALL_USER" ] || [ "$INSTALL_USER" = "root" ]; then
        INSTALL_USER=$(cat /tmp/datadog-install-user || echo 'root')
    fi
    echo "INSTALL_USER: $INSTALL_USER"

    USER_HOME=$(sudo -Hu "$INSTALL_USER" sh -c 'echo $HOME')

    if [ -e "$CONF_DIR/datadog.conf" ] || [ -e "$CONF_DIR/datadog.yaml" ]; then
        echo "# State at the beginning"
        echo "## Agent version"
        grep AGENT_VERSION $INSTALL_DIR/agent/config.py || echo "No config.py file (agent 5)"
        datadog-agent version || echo "No datadog-agent binary version (agent 6)"
        echo "## $INSTALL_DIR"
        ls -al $INSTALL_DIR || echo "No agent installed"
        echo "## $APP_DIR/Contents/Resources"
        ls -al "$APP_DIR/Contents/Resources" || echo "No app installed"

        echo '# Stop old agent'
        echo '## Trying to stop agent 5'
        $INSTALL_DIR/bin/datadog-agent stop || true
        echo '## Trying to stop agent 6'
        sudo -Hu "$INSTALL_USER" launchctl stop com.datadoghq.agent || true
        echo '## Trying to kill agent GUI'
        kill "$(pgrep -f 'Datadog Agent.app')"

        echo '## Trying to unload agent 6 launchd service'
        sudo -Hu "$INSTALL_USER" launchctl unload -w "$USER_HOME/Library/LaunchAgents/com.datadoghq.agent.plist" || true

        # Save old conf
        rm -rvf /tmp/{checks,conf}.d/* /tmp/datadog.conf /tmp/datadog.yaml
        mkdir -vp /tmp/{conf,checks}.d
        cp -vf $CONF_DIR/datadog.conf /tmp
        cp -vf $CONF_DIR/datadog.yaml /tmp
        cp -vfR $CONF_DIR/conf.d/* /tmp/conf.d
        find /tmp/conf.d '(' -name '*.yaml.example' -o -name '*.yaml.default' ')' -delete -print # don't save old example and default yamls
        cp -vfR $CONF_DIR/checks.d/* /tmp/checks.d
    fi

    echo '# Deleting old datadog-agent link'
    rm -vf /usr/local/bin/datadog-agent

    echo '# Deleting old datadog-agent files'
    rm -rf $INSTALL_DIR/agent || true
    rm -rf $INSTALL_DIR/checks.d || true

    echo "# Disabling the login launch of the app"
    sudo -u "$INSTALL_USER" osascript -e 'tell application "System Events" to delete every login item whose name is "Datadog Agent"'

    # Debriefing time
    echo "# State at the end"
    echo "## Agent version"
    grep AGENT_VERSION $INSTALL_DIR/agent/config.py || echo "No config.py file (agent 5)"
    datadog-agent version || echo "No datadog-agent binary version (agent 6)"
    echo "## $INSTALL_DIR"
    ls -al $INSTALL_DIR || echo "No agent installed"
    echo "## $APP_DIR/Contents/Resources"
    ls -al "$APP_DIR/Contents/Resources" || echo "No app installed"
fi

exit 0
